"""
什么是闭包？
    外层函数嵌套里层函数，在里层函数中如果访问了外部函数的局部变量，那么该`局部变量和里层函数统一称为闭包。
        里层函数也叫作闭包函数

    1.闭包函数可以访问外层函数的局部变量。即使外层函数调用已经结束，对于闭包函数，依然可以访问外层函数的局部变量。
    2.闭包函数在访问外层函数的局部变量时，总是访问该变量的最新值。
"""


def outer():
    x = 0

    def inner():
        nonlocal x
        x += 1
        return x

    return inner


res = outer()
print(res)
print(res())
print(res())
print(res())
print(res())

print('X' * 20)

list1 = (x for x in range(1, 11))
print(next(list1))
print(next(list1))
print(next(list1))
print(next(list1))


def outer1():
    x = 0

    def inner(y):
        nonlocal x
        x += y
        return x

    return inner


print(outer1)
res1 = outer1()
r = res1(2)
print(r)
r = res1(2)
print(r)
r = res1(2)
print(r)


# print(res1(2))
# print(res1(2))
# print(res1(2))


# 装饰了原函数,让原函数的功能更加强大
# 参数是个函数
def zhuangshi(fun_yuan):
    def inner():
        print('zhuangshi ---ing')
        fun_yuan()
        print('zhuangshi ---end')

    return inner


@zhuangshi
def yuan():
    print('hello...')


# yuan()
## 此处传的是 函数名 ,不是函数的调用结果
# zhuangshi(yuan)()
yuan()

# 为什么用装饰器 而不是直接修改原函数呢
# 原函数可能不受我们掌控

